package com.njust.service.Impl;

import com.njust.common.Const;
import com.njust.common.ServerRespone;
import com.njust.dataobject.*;
import com.njust.enums.*;
import com.njust.mapper.*;
import com.njust.service.SysParamService;
import com.njust.service.TableService;
import com.njust.service.TrainService;
import com.njust.utils.CompareUtil;
import com.njust.utils.DateUtil;
import com.njust.utils.StringUtil;
import com.njust.utils.TcpUtil;
import com.njust.vo.*;
import com.njust.vo.TalbeVO.DetailVO;
import com.njust.vo.TalbeVO.TableVO;
import com.njust.vo.TrainParamVO.TrainParamVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.swing.MenuItemLayoutHelper;

import java.io.IOException;
import java.text.ParseException;
import java.util.*;

@Service
public class TrainServiceImlp implements TrainService {

    @Autowired
    private TrainInfoMapper trainInfoMapper;

    @Autowired
    private TrainFaultMapper trainFaultMapper;

    @Autowired
    private TrainDataMapper trainDataMapper;

    @Autowired
    private VtInfoMapper vtInfoMapper;

    @Autowired
    private MotorInfoMapper motorInfoMapper;

    @Autowired
    private SysParamService sysParamService;


    @Autowired
    private TableService tableService;

    /**
     * 实时返回最新的数据
     * @param pre
     * @return
     * @throws ParseException
     */
    @Override
    public ServerRespone realShow(String pre) throws ParseException {
        List<TrainInfo> trainInfos=new ArrayList<>();
        //返回的数据
        TrainInfoVO trainInfoVO=new TrainInfoVO();

        Date firsttime = DateUtil.String2Date(pre);
        long time=firsttime.getTime()+86400000;
        Date secondtime=new Date(time);

        TrainInfo trainInfo = trainInfoMapper.findTrainInfoByLastTrainId();
        if(trainInfo==null){
            return ServerRespone.createByErrorMessage("无数据");
        }

        TrainInfoExample trainInfoExample = new TrainInfoExample();
        TrainInfoExample.Criteria criteria = trainInfoExample.createCriteria();

        if(trainInfo.getTrainId()!=null){
            trainInfoVO.setTrainId(trainInfo.getTrainId());
            criteria.andTrainIdEqualTo(trainInfo.getTrainId());
            criteria.andTrainDateBetween(firsttime,secondtime);
            trainInfoExample.setOrderByClause("train_onlyid DESC");
        }

        //根据车牌查询出当天的所有这个车牌号的数据
        List<TrainInfo> trainInfoList = trainInfoMapper.selectByExample(trainInfoExample);

        if(trainInfoList.size()==0){
            return ServerRespone.createByErrorMessage("无数据");
        }
        for (TrainInfo trainInfo1:trainInfoList){
            TrainInfo trainInfo2=new TrainInfo();
            trainInfo2.setTrainOnlyid(trainInfo1.getTrainOnlyid());
            trainInfo2.setTrainState(trainInfo1.getTrainState());
            trainInfo2.setTrainDirection(trainInfo1.getTrainDirection());
            trainInfos.add(trainInfo2);
        }
        trainInfoVO.setTrainInfoList(trainInfos);
        return ServerRespone.createBySuccess(trainInfoVO);
    }

    /**
     * 实时返回所有的数据
     * @param pre
     * @return
     * @throws ParseException
     */
    @Override
    public ServerRespone realShowall(String pre) throws ParseException {
        Map<String,List<TrainInfo>> traininfoMap=new HashMap<>();
        List<String> trainIdList=Arrays.asList(Const.TRAINID);
        Date firsttime = DateUtil.String2Date(pre);
        long time=firsttime.getTime()+86400000;
        Date secondtime=new Date(time);
        //进行所有车数据的查询
        for (String trainId:trainIdList){
            List<TrainInfo> trainInfos=new ArrayList<>();
            TrainInfoExample trainInfoExample=new TrainInfoExample();
            TrainInfoExample.Criteria criteria = trainInfoExample.createCriteria();
            criteria.andTrainIdEqualTo(trainId);
            criteria.andTrainDateBetween(firsttime,secondtime);
            trainInfoExample.setOrderByClause("train_date DESC");

            List<TrainInfo> trainInfos1 = trainInfoMapper.selectByExample(trainInfoExample);
            if(trainInfos1.size()==0){
                continue;
            }
            for (TrainInfo tf:trainInfos1){
                TrainInfo trainInfo=new TrainInfo();
                trainInfo.setTrainOnlyid(tf.getTrainOnlyid());
                trainInfo.setTrainState(tf.getTrainState());
                trainInfo.setTrainDirection(tf.getTrainDirection());
                trainInfos.add(trainInfo);
            }
            traininfoMap.put(trainId,trainInfos);
        }
        if(traininfoMap.entrySet().size()==0){
            return ServerRespone.createByErrorMessage("无数据");
        }
        return ServerRespone.createBySuccess(traininfoMap);
    }


    /**
     * 报警弹出异常车的所有信息
     * @param trainOnlyid
     * @return
     */
    @Override
    public ServerRespone warn(Long trainOnlyid) {
        TrainFaultExample trainFaultExample = new TrainFaultExample();

        TrainFaultExample.Criteria criteria = trainFaultExample.createCriteria();
        if(trainOnlyid!=null){
            criteria.andTrainOnlyidEqualTo(trainOnlyid);
        }else{
            return ServerRespone.createByErrorMessage("无数据");
        }
        //查询出所有的与该ID有关的信息
        List<TrainFault> trainFaultList = trainFaultMapper.selectByExample(trainFaultExample);


        if(trainFaultList.size()==0){
            return ServerRespone.createByErrorMessage("无数据");
        }

        List<Integer> codelist=new ArrayList<>();
        List<String> msglist=new ArrayList<>();
        TrainFaultVO trainFaultVO=new TrainFaultVO();
        //vo转换
        for (TrainFault trainFault:trainFaultList){

            // (1 1->1)  (2 1->2)  (3-1->3)  (1 2->4) (2 2->5) (3 2->6) (4->7)

            //报警
            if(trainFault.getFaultType().equals(SelectType.ZHENDONG.getCode()) && trainFault.getFaultRank().equals
                    (FaultRank.ALARM.getCode())){
                codelist.add(FaultMessage.ZHENDONGALARM.getCode());
                msglist.add(FaultMessage.ZHENDONGALARM.getMsg());
            }
            if(trainFault.getFaultType().equals(SelectType.ZHOUWEN.getCode()) && trainFault.getFaultRank().equals
                    (FaultRank.ALARM.getCode())){
                codelist.add(FaultMessage.ZHOUWENALARM.getCode());
                msglist.add(FaultMessage.ZHOUWENALARM.getMsg());
            }
            if(trainFault.getFaultType().equals(SelectType.MOTOR.getCode()) && trainFault.getFaultRank().equals
                    (FaultRank.ALARM.getCode())){
                codelist.add(FaultMessage.MOTORALARM.getCode());
                msglist.add(FaultMessage.MOTORALARM.getMsg());
            }

            //预警
            if(trainFault.getFaultType().equals(SelectType.ZHENDONG.getCode()) && trainFault.getFaultRank().equals
                    (FaultRank.WARN.getCode())){
                codelist.add(FaultMessage.ZHENDONGWARN.getCode());
                msglist.add(FaultMessage.ZHENDONGALARM.getMsg());
            }
            if(trainFault.getFaultType().equals(SelectType.ZHOUWEN.getCode()) && trainFault.getFaultRank().equals
                    (FaultRank.WARN.getCode())){
                codelist.add(FaultMessage.ZHOUWENWARN.getCode());
                msglist.add(FaultMessage.ZHOUWENWARN.getMsg());
            }
            if(trainFault.getFaultType().equals(SelectType.MOTOR.getCode()) && trainFault.getFaultRank().equals
                    (FaultRank.WARN.getCode())){
                codelist.add(FaultMessage.MOTORWARN.getCode());
                msglist.add(FaultMessage.MOTORWARN.getMsg());
            }
            //异常
            if(trainFault.getFaultType().equals(SelectType.ABNORMAL.getCode())){
                codelist.add(FaultMessage.ABNORMAL.getCode());
                msglist.add(FaultMessage.ABNORMAL.getMsg());
            }


            trainFaultVO.setTrainDate(DateUtil.Date2String(trainFault.getTrainDate()));
        }
        trainFaultVO.setFaultCode(codelist);
        trainFaultVO.setFaultInfo(msglist);


        return ServerRespone.createBySuccess(trainFaultVO);
    }

    /**
     * 返回列车的详细数据
     * @param trainOnlyid
     * @return
     */
    @Override
    public ServerRespone showDetailByTrainOnlyId(Long trainOnlyid) {

        //根据唯一编号查出所有的数据
        TrainInfo trainInfo = trainInfoMapper.selectByPrimaryKey(trainOnlyid);
        //虽然是个list  但实际上就只有一条数据额！！！
        TrainData td = trainDataMapper.selectByPrimaryKey(trainOnlyid);

        if(td==null || trainInfo==null){
            return ServerRespone.createByErrorMessage("无数据");
        }

        //查出阈值 但是一开始没有怎么办 必须人为在数据库中进行设置
        //读出阈值
        ServerRespone serverRespone = sysParamService.showParam();
        TrainParamVO trainParam = (TrainParamVO)serverRespone.getData();

        if(trainParam== null){
            return ServerRespone.createByErrorMessage("请先设置阈值");
        }

        TableVO tableVO=new TableVO();
        Map<String,DetailVO> contentMap=new HashMap<>();
        tableVO.setTrainId(trainInfo.getTrainId());
        tableVO.setTrainOnlyid(trainInfo.getTrainOnlyid());
        tableVO.setTrainState(trainInfo.getTrainState());
        tableVO.setTrainId(trainInfo.getTrainId());
        tableVO.setTrainDate(DateUtil.Date2String(trainInfo.getTrainDate()));
        //添加温升的数据没有设置相应的状态
        //轴温温升并设置其状态
        DetailVO zwTempIncVO = new DetailVO();
        if(td.getZxTempinc().compareTo(trainParam.getZwincWarn())==1){
            zwTempIncVO.setColor(RankColor.ALARM.getCode());
        } else if(td.getZxTempinc().compareTo(trainParam.getZwincWarn())==1 && td.getZxTempinc().compareTo
                (trainParam.getZwAlarm())==-1){
            zwTempIncVO.setColor(RankColor.WARN.getCode());
        }
        zwTempIncVO.setContent(td.getZxTempinc().toString());
        contentMap.put("ZWINC",zwTempIncVO);

        //电机温度温升并设置其状态
        DetailVO motorTempIncVO = new DetailVO();
        if(td.getMotorTempinc().compareTo(trainParam.getMotortempincWarn())==1){
            motorTempIncVO.setColor(RankColor.ALARM.getCode());
        } else if(td.getMotorTempinc().compareTo(trainParam.getMotortempincWarn())==1 && td.getMotorTempinc().compareTo
                (trainParam.getMotortempincAlarm())==-1){
            motorTempIncVO.setColor(RankColor.WARN.getCode());
        }
        motorTempIncVO.setContent(td.getMotorTempinc().toString());
        contentMap.put("MOTOTTEMPINC",motorTempIncVO);

        //均方根
        DetailVO jfgdetailVO=new DetailVO();
        if(td.getJfgAlarm()>0){
            jfgdetailVO.setColor(RankColor.ALARM.getCode());
        }else if(td.getJfgWarn()>0){
            jfgdetailVO.setColor(RankColor.WARN.getCode());
        }else {
        }
        jfgdetailVO.setContent(StringUtil.alarmandwarn(td.getJfgAlarm(),td.getJfgWarn()));
        contentMap.put(ZdType.JFG.getMsg(),jfgdetailVO);

        //峰值
        DetailVO fzdetailVO=new DetailVO();
        if(td.getFzAlarm()>0){
            fzdetailVO.setColor(RankColor.ALARM.getCode());
        }else if(td.getFzWarn()>0){
            fzdetailVO.setColor(RankColor.WARN.getCode());
        }else {
        }
        fzdetailVO.setContent(StringUtil.alarmandwarn(td.getFzAlarm(),td.getFzWarn()));
        contentMap.put(ZdType.FZ.getMsg(),fzdetailVO);

        //峰值因子
        DetailVO fzyzdetailVO=new DetailVO();
        if(td.getFzyzAlarm()>0){
            fzyzdetailVO.setColor(RankColor.ALARM.getCode());
        }else if(td.getFzyzWarn()>0){
            fzyzdetailVO.setColor(RankColor.WARN.getCode());
        }else {
        }
        fzyzdetailVO.setContent(StringUtil.alarmandwarn(td.getFzyzAlarm(),td.getFzyzWarn()));
        contentMap.put(ZdType.FZYZ.getMsg(),fzyzdetailVO);

        //峭度
        DetailVO qdetailVO=new DetailVO();
        if(td.getQdAlarm()>0){
            qdetailVO.setColor(RankColor.ALARM.getCode());
        }else if(td.getQdWarn()>0){
            qdetailVO.setColor(RankColor.WARN.getCode());
        }else {
        }
        qdetailVO.setContent(StringUtil.alarmandwarn(td.getQdAlarm(),td.getQdWarn()));
        contentMap.put(ZdType.QD.getMsg(),qdetailVO);

        //峭度因子
        DetailVO qdyzdetailVO=new DetailVO();
        if(td.getQdyzAlarm()>0){
            qdyzdetailVO.setColor(RankColor.ALARM.getCode());
        }else if(td.getQdyzWarn()>0){
            qdyzdetailVO.setColor(RankColor.WARN.getCode());
        }else {
        }
        qdyzdetailVO.setContent(StringUtil.alarmandwarn(td.getQdyzAlarm(),td.getQdyzWarn()));
        contentMap.put(ZdType.QDYZ.getMsg(),qdyzdetailVO);

        //轴温
        DetailVO zwdetailVO=new DetailVO();
        //大于
        if(td.getZxTemp().compareTo(trainParam.getZwAlarm())==1){
            zwdetailVO.setColor(RankColor.ALARM.getCode());
        } else if(td.getZxTemp().compareTo(trainParam.getZwWarn())==1 && td.getZxTemp().compareTo
                (trainParam.getZwAlarm())==-1){
            zwdetailVO.setColor(RankColor.WARN.getCode());
        }
        zwdetailVO.setContent(td.getZxTemp().toString());
        contentMap.put("ZW",zwdetailVO);
        //电机温度
        DetailVO motordetailVO=new DetailVO();
        if(td.getMotorTemp().compareTo(trainParam.getMotortempAlarm())==1){
            motordetailVO.setColor(RankColor.ALARM.getCode());
        } else if(td.getMotorTemp().compareTo(trainParam.getMotortempWarn())==1 && td.getMotorTemp().compareTo
                (trainParam.getMotortempAlarm())==-1){
            motordetailVO.setColor(RankColor.WARN.getCode());
        }
        motordetailVO.setContent(td.getMotorTemp().toString());
        contentMap.put("MOTOR",motordetailVO);
        tableVO.setDetailVOMap(contentMap);
        return ServerRespone.createBySuccess(tableVO);
    }

    /**
     * 返回振动的详细数据
     * @param trainOnlyid
     * @return
     */
    @Override
    public ServerRespone zhendongDetail(Long trainOnlyid){
        List<VtInfoVO> vtInfoVOS=new ArrayList<>();
        VtInfoExample vtInfoExample=new VtInfoExample();
        VtInfoExample.Criteria criteria = vtInfoExample.createCriteria();
        criteria.andTrainOnlyidEqualTo(trainOnlyid);
        List<VtInfo> vtInfos = vtInfoMapper.selectByExample(vtInfoExample);
        if(vtInfos.size()==0){
            return ServerRespone.createByErrorMessage("无数据");
        }
        ServerRespone serverRespone = sysParamService.showParam();
        TrainParamVO trainParam = (TrainParamVO)serverRespone.getData();
        if(trainParam==null){
            return ServerRespone.createByErrorMessage("请先输入阈值");
        }
        for (VtInfo vtInfo:vtInfos){
            VtInfoVO vtInfoVO=new VtInfoVO();
            BeanUtils.copyProperties(vtInfo,vtInfoVO);
            vtInfoVO.setCarriageWheel(StringUtil.connectStr(vtInfo.getCarriageNum(),vtInfo.getWheelNum()));

            //均方根
            vtInfoVO.setJfgState(CompareUtil.compare(1,trainParam.getJfgWarn().doubleValue()
                    ,trainParam.getJfgAlarm().doubleValue(),vtInfo.getJfgValue().doubleValue()));

            //峭度
            vtInfoVO.setQdState(CompareUtil.compare(1,trainParam.getQdWarn().doubleValue()
                    ,trainParam.getQdAlarm().doubleValue(),vtInfo.getQdValue().doubleValue()));

            //峭度因子
            vtInfoVO.setQdyzState(CompareUtil.compare(1,trainParam.getQdyzWarn().doubleValue()
                    ,trainParam.getQdyzAlarm().doubleValue(),vtInfo.getQdyzValue().doubleValue()));

            //峰值
            vtInfoVO.setFzState(CompareUtil.compare(1,trainParam.getFzWarn().doubleValue()
                    ,trainParam.getFzyzAlarm().doubleValue(),vtInfo.getFzValue().doubleValue()));

            //峰值因子
            vtInfoVO.setFzyzState(CompareUtil.compare(1,trainParam.getFzyzWarn().doubleValue()
                    ,trainParam.getFzyzAlarm().doubleValue(),vtInfo.getFzyzValue().doubleValue()));

            vtInfoVO.setZxState(CompareUtil.compare(1,trainParam.getZwWarn().doubleValue(),trainParam.getZwAlarm()
                    .doubleValue(),vtInfo.getZxTemp().doubleValue()));

            //设置轴温温升的额状态,设置完毕
            vtInfoVO.setZxTempIncState(CompareUtil.compare(1,trainParam.getZwincWarn().doubleValue(),trainParam.getZwincAlarm()
                    .doubleValue(),vtInfo.getZxTempinc().doubleValue()));

            vtInfoVOS.add(vtInfoVO);
        }
        return ServerRespone.createBySuccess(vtInfoVOS);
    }

    /**
     * 返回电机的详细数据
     * @param trainOnlyid
     * @return
     */
    @Override
    public ServerRespone motorDetail(Long trainOnlyid) {
        List<MotorInfoVO> motorInfoVOS=new ArrayList<>();

        MotorInfoExample motorInfoExample=new MotorInfoExample();
        MotorInfoExample.Criteria criteria = motorInfoExample.createCriteria();
        criteria.andTrainOnlyidEqualTo(trainOnlyid);
        List<MotorInfo> motorInfoList = motorInfoMapper.selectByExample(motorInfoExample);
        if(motorInfoList.size()==0){
            return ServerRespone.createByErrorMessage("无数据");
        }
        ServerRespone serverRespone = sysParamService.showParam();
        TrainParamVO trainParam = (TrainParamVO)serverRespone.getData();
        if(trainParam==null){
            return ServerRespone.createByErrorMessage("请先输入阈值");
        }

        for (MotorInfo motorInfo:motorInfoList){
            MotorInfoVO motorInfoVO=new MotorInfoVO();
            BeanUtils.copyProperties(motorInfo,motorInfoVO);
            motorInfoVO.setCarriageMotor(StringUtil.connectStr(motorInfo.getCarriageNum(),motorInfo.getMotorNum()));
            //显示颜色
            motorInfoVO.setMotorTempState(CompareUtil.compare(1,trainParam.getMotortempWarn().doubleValue()
                    ,trainParam.getMotortempAlarm().doubleValue(),motorInfo.getMotorTemp().doubleValue()));
            motorInfoVOS.add(motorInfoVO);
            //设置电机温升值得状态
            motorInfoVO.setMotorTempIncState(CompareUtil.compare(1,trainParam.getMotortempincWarn().doubleValue()
                    ,trainParam.getMotortempincAlarm().doubleValue(), motorInfo.getMotorTempinc().doubleValue()));

        }
        return ServerRespone.createBySuccess(motorInfoVOS);
    }

    /**
     * 运营结束最后10条记录
     * @param pre
     * @param after
     * @return
     */
    @Override
    public ServerRespone todayLast10(Date pre, Date after) {
        //返回数据的封装
        List<TableVO> tableVOS=new ArrayList<>();
        TrainInfoExample trainInfoExample=new TrainInfoExample();
        TrainInfoExample.Criteria criteria = trainInfoExample.createCriteria();
        criteria.andTrainDateBetween(pre,after);
        trainInfoExample.setOrderByClause("train_date DESC");

        List<TrainInfo> trainInfos = trainInfoMapper.selectByExample(trainInfoExample);
        if(trainInfos.size()==0){
            return ServerRespone.createByErrorMessage("无数据");
        }

        //唯一编号
        List<Long> trainOnlyIdList=new ArrayList<>();
        //拿到唯一编号
        for (TrainInfo trainInfo:trainInfos){
            trainOnlyIdList.add(trainInfo.getTrainOnlyid());
        }

        //查出当天所有的相关信息
        TrainDataExample trainDataExample=new TrainDataExample();
        TrainDataExample.Criteria criteria1 = trainDataExample.createCriteria();
        criteria1.andTrainOnlyidIn(trainOnlyIdList);
        List<TrainData> trainData = trainDataMapper.selectByExample(trainDataExample);

        if(trainData.size()==0){
            return ServerRespone.createByErrorMessage("无数据");
        }
        //读出阈值
        ServerRespone serverRespone = sysParamService.showParam();
        TrainParamVO trainParam = (TrainParamVO)serverRespone.getData();
        if(trainParam==null){
            return ServerRespone.createByErrorMessage("请先设置阈值");
        }

        for (TrainInfo trainInfo:trainInfos){
            for (TrainData td:trainData){
                if(td.getTrainOnlyid().equals(trainInfo.getTrainOnlyid())){
                    tableService.assembleTableData(tableVOS, trainParam, trainInfo, td);
                }else {
                    continue;
                }
            }
        }
        return ServerRespone.createBySuccess(tableVOS);
    }


    /**
     * 添加三色灯
     */

    /**
     * 1 报警 2是预警 0表示恢复
     *
     * @param warnRank
     * @return
     * @throws IOException
     */
    @Override
    public ServerRespone deviceState(Integer warnRank) throws IOException {
        TcpUtil.action(warnRank);
        return ServerRespone.createBySuccess();
    }

}
